import { MODEL_NAME } from '../../constants/model-names';
import type {
  BattleLevelModel,
  CultivationSkillModel,
  InventoryModel,
  PlayerProgressModel,
  RealmModel,
  SectModel,
  SpiritualRootModel,
  WalletModel,
} from '../../model';
import { RealmReader } from '../../model/realm/realm-reader';
import { CURRENCY_TYPE } from '../../model/wallet';
import { ItemReader } from '../item/reader';
import type { PlayerStateSystem } from '../player-state';
import { SpiritualRootReader } from '../spiritual-root/reader';
import {
  CONDITION_TYPE,
  type AndCondition,
  type BattleLevelCondition,
  type Condition,
  type ConditionProgress,
  type CultivationSkillCondition,
  type CultivationSkillStudyCountCondition,
  type ItemCondition,
  type KillMonsterCondition,
  type LifeCondition,
  type NotCondition,
  type OrCondition,
  type RealmCondition,
  type SectJobCondition,
  type SpiritStoneCondition,
  type SpiritualRootCondition,
} from './type';

export class ConditionCheckerSystem {
  private playerStateSystem: PlayerStateSystem;
  constructor(playerStateSystem: PlayerStateSystem) {
    this.playerStateSystem = playerStateSystem;
  }

  // 统一条件检查入口
  checkCondition(condition: Condition): boolean {
    switch (condition.type) {
      case CONDITION_TYPE.REALM:
        return this.checkRealmCondition(condition);
      case CONDITION_TYPE.CULTIVATION_SKILL_STUDY_COUNT:
        return this.checkCultivationSkillStudyCountCondition(condition);
      case CONDITION_TYPE.SPIRITUAL_ROOT:
        return this.checkSpiritualRootCondition(condition);
      case CONDITION_TYPE.KILL_MONSTER:
        return this.checkKillMonsterCondition(condition);
      case CONDITION_TYPE.ITEM:
        return this.checkItemCondition(condition);
      case CONDITION_TYPE.SECT_JOB:
        return this.checkSectJobCondition(condition);
      case CONDITION_TYPE.BATTLE_LEVEL:
        return this.checkBattleLevelCondition(condition);
      case CONDITION_TYPE.SPIRIT_STONE:
        return this.checkSpiritStoneCondition(condition);
      case CONDITION_TYPE.LIFE:
        return this.checkLifeCondition(condition);
      case CONDITION_TYPE.CULTIVATION_SKILL:
        return this.checkCultivationSkillCondition(condition);
      case CONDITION_TYPE.AND:
        return this.checkAndCondition(condition);
      case CONDITION_TYPE.OR:
        return this.checkOrCondition(condition);
      case CONDITION_TYPE.NOT:
        return this.checkNotCondition(condition);

      default:
        console.warn('未知的条件类型:', (condition as any).type);
        return false;
    }
  }

  getConditionProgress(condition: Condition): ConditionProgress {
    switch (condition.type) {
      case CONDITION_TYPE.REALM:
        return this.getRealmProgress(condition);
      case CONDITION_TYPE.CULTIVATION_SKILL_STUDY_COUNT:
        return this.getCultivationSkillStudyCountProgress(condition);
      case CONDITION_TYPE.SPIRITUAL_ROOT:
        return this.getSpiritualRootProgress(condition);
      case CONDITION_TYPE.KILL_MONSTER:
        return this.getKillMonsterProgress(condition);
      case CONDITION_TYPE.ITEM:
        return this.getItemProgress(condition);
      case CONDITION_TYPE.SECT_JOB:
        return this.getSectJobProgress(condition);
      case CONDITION_TYPE.BATTLE_LEVEL:
        return this.getBattleLevelProgress(condition);
      case CONDITION_TYPE.SPIRIT_STONE:
        return this.getSpiritStoneProgress(condition);
      case CONDITION_TYPE.LIFE:
        return this.getLifeProgress(condition);
      case CONDITION_TYPE.CULTIVATION_SKILL:
        return this.getCultivationSkillProgress(condition);
      case CONDITION_TYPE.AND:
        return this.getAndProgress(condition);
      case CONDITION_TYPE.OR:
        return this.getOrProgress(condition);
      case CONDITION_TYPE.NOT:
        return this.getNotProgress(condition);
      default:
        return {
          isMet: false,
          current: 0,
          required: 1,
          description: '未知条件类型',
          progress: 0,
          type: 'UNKNOWN',
        };
    }
  }

  getConditionsProgress(conditions: Condition[]): ConditionProgress[] {
    const progresses: ConditionProgress[] = [];
    for (const condition of conditions) {
      progresses.push(this.getConditionProgress(condition));
    }
    return progresses;
  }

  private getRealmProgress(condition: RealmCondition): ConditionProgress {
    const realmModel = this.playerStateSystem.getModel<RealmModel>(
      MODEL_NAME.REALM
    );
    const realmState = realmModel.getSnapshot();
    const currentRealmConfig = RealmReader.getRealmConfigByLevel(
      condition.realm
    );
    const isMet = this.checkRealmCondition(condition);
    const required = condition.realm;
    const current = realmState.realm;
    const progress = Math.min(current / required, 1);

    return {
      isMet,
      current,
      required,
      description: `境界要求: [${currentRealmConfig.name}]`,
      progress,
      type: CONDITION_TYPE.REALM,
    };
  }

  private getCultivationSkillStudyCountProgress(
    _condition: CultivationSkillStudyCountCondition
  ): ConditionProgress {
    return {
      isMet: false,
      current: 0,
      required: 1,
      description: '未实现',
      progress: 0,
      type: CONDITION_TYPE.CULTIVATION_SKILL_STUDY_COUNT,
    };
  }

  private getSpiritualRootProgress(
    condition: SpiritualRootCondition
  ): ConditionProgress {
    const isMet = this.checkSpiritualRootCondition(condition);
    const name = condition.spiritualRoot
      .map((element) => {
        return SpiritualRootReader.getName(element);
      })
      .join('、');
    return {
      isMet,
      current: isMet ? 1 : 0,
      required: 1,
      description: `需要 [${name}] 灵根`,
      progress: 0,
      type: CONDITION_TYPE.SPIRITUAL_ROOT,
    };
  }

  private getKillMonsterProgress(
    _condition: KillMonsterCondition
  ): ConditionProgress {
    return {
      isMet: false,
      current: 0,
      required: 1,
      description: '未实现',
      progress: 0,
      type: CONDITION_TYPE.KILL_MONSTER,
    };
  }

  private getItemProgress(condition: ItemCondition): ConditionProgress {
    const inventoryModel = this.playerStateSystem.getModel<InventoryModel>(
      MODEL_NAME.INVENTORY
    );
    const isMet = this.checkItemCondition(condition);
    const itemCount = inventoryModel.getQuantity(condition.itemId);
    const itemConfig = ItemReader.getConfig(condition.itemId);
    return {
      isMet,
      current: itemCount,
      required: condition.count,
      description: `拥有 [${itemConfig?.name || '未知物品'}] ${
        condition.count
      } 个 (${itemCount}/${condition.count})`,
      progress: Math.max(0, Math.min(1, itemCount / condition.count)),
      type: CONDITION_TYPE.ITEM,
    };
  }

  private getSectJobProgress(condition: SectJobCondition): ConditionProgress {
    const sectModel = this.playerStateSystem.getModel<SectModel>(
      MODEL_NAME.SECT
    );
    const currentSectJobConfig = sectModel.getCurrentSectJob();
    const requiredSectJobConfig = sectModel.getSectJobConfigById(condition.job);
    const isMet = this.checkSectJobCondition(condition);
    const current = currentSectJobConfig?.config.level || 1;
    const required = condition.job;
    const jobName = requiredSectJobConfig?.config.name || '未知职位';

    return {
      isMet,
      current,
      required,
      description: `宗门职位: [${jobName}]`,
      progress: Math.max(0, Math.min(1, current / required)),
      type: CONDITION_TYPE.SECT_JOB,
    };
  }

  private getBattleLevelProgress(
    condition: BattleLevelCondition
  ): ConditionProgress {
    const battleLevelModel = this.playerStateSystem.getModel<BattleLevelModel>(
      MODEL_NAME.BATTLE_LEVEL
    );
    const level = battleLevelModel.getLevelInfo().level;
    const isMet = this.checkBattleLevelCondition(condition);
    return {
      isMet,
      current: level,
      required: condition.level,
      description: `战斗等级: ${condition.level} 级`,
      progress: Math.max(0, Math.min(1, level / condition.level)),
      type: CONDITION_TYPE.BATTLE_LEVEL,
    };
  }

  private getSpiritStoneProgress(
    condition: SpiritStoneCondition
  ): ConditionProgress {
    const walletModel = this.playerStateSystem.getModel<WalletModel>(
      MODEL_NAME.WALLET
    );
    const spiritStone = walletModel.getBalance(CURRENCY_TYPE.SPIRIT_STONE);
    const isMet = this.checkSpiritStoneCondition(condition);
    return {
      isMet,
      current: spiritStone,
      required: condition.count,
      description: `灵石: ${condition.count} 个`,
      progress: Math.max(0, Math.min(1, spiritStone / condition.count)),
      type: CONDITION_TYPE.SPIRIT_STONE,
    };
  }

  private getLifeProgress(condition: LifeCondition): ConditionProgress {
    const playerProgressModel =
      this.playerStateSystem.getModel<PlayerProgressModel>(
        MODEL_NAME.PLAYER_PROGRESS
      );
    const years = playerProgressModel.getLifeYears();
    const isMet = this.checkLifeCondition(condition);
    return {
      isMet,
      current: years,
      required: condition.years,
      description: `寿元到达 ${condition.years} 年`,
      progress: Math.max(0, Math.min(1, years / condition.years)),
      type: CONDITION_TYPE.LIFE,
    };
  }

  private getCultivationSkillProgress(
    condition: CultivationSkillCondition
  ): ConditionProgress {
    const cultivationSkillModel =
      this.playerStateSystem.getModel<CultivationSkillModel>(
        MODEL_NAME.CULTIVATION_SKILL
      );
    const isMet = cultivationSkillModel.isCultivationSkillLearned(condition.id);
    const cultivationSkillConfig = cultivationSkillModel.getItemConfig(
      condition.id
    );
    return {
      isMet,
      current: 0,
      required: 0,
      description: `需要学会 [${cultivationSkillConfig?.name}]`,
      progress: isMet ? 1 : 0,
      type: CONDITION_TYPE.CULTIVATION_SKILL,
    };
  }

  private getAndProgress(condition: AndCondition): ConditionProgress {
    const subProgresses = this.getConditionsProgress(condition.conditions);
    const metCount = subProgresses.filter((p) => p.isMet).length;
    const isMet = metCount === subProgresses.length;

    return {
      isMet,
      current: metCount,
      required: subProgresses.length,
      description: condition.description || '满足所有条件',
      progress: subProgresses.length > 0 ? metCount / subProgresses.length : 1,
      type: CONDITION_TYPE.AND,
      subConditions: subProgresses, // 添加子条件信息用于UI显示
    };
  }

  private getOrProgress(condition: OrCondition): ConditionProgress {
    const subProgresses = this.getConditionsProgress(condition.conditions);
    const metCount = subProgresses.filter((p) => p.isMet).length;
    const isMet = metCount > 0;

    return {
      isMet,
      current: metCount,
      required: 1, // OR条件只需要满足一个
      description: condition.description || '满足任一条件',
      progress: isMet ? 1 : 0,
      type: CONDITION_TYPE.OR,
      subConditions: subProgresses,
    };
  }

  private getNotProgress(condition: NotCondition): ConditionProgress {
    const subProgress = this.getConditionProgress(condition.condition);
    const isMet = !subProgress.isMet;

    return {
      isMet,
      current: isMet ? 1 : 0,
      required: 1,
      description:
        condition.description || `不满足: ${subProgress.description}`,
      progress: isMet ? 1 : 0,
      type: CONDITION_TYPE.NOT,
      subCondition: subProgress,
    };
  }

  // 检查多个条件
  checkConditions(conditions: Condition[]): boolean {
    for (const condition of conditions) {
      if (!this.checkCondition(condition)) {
        return false;
      }
    }
    return true;
  }

  private checkRealmCondition(condition: RealmCondition): boolean {
    const realmModel = this.playerStateSystem.getModel<RealmModel>(
      MODEL_NAME.REALM
    );
    const realm = realmModel.getRealm();
    return condition.realm <= realm;
  }

  private checkCultivationSkillStudyCountCondition(
    condition: CultivationSkillStudyCountCondition
  ): boolean {
    const cultivationSkillModel =
      this.playerStateSystem.getModel<CultivationSkillModel>(
        MODEL_NAME.CULTIVATION_SKILL
      );
    const count = cultivationSkillModel.getLearnedCultivationSkillCount();
    return condition.count <= count;
  }

  private checkSpiritualRootCondition(
    condition: SpiritualRootCondition
  ): boolean {
    if (condition.spiritualRoot.length === 0) return true;
    const spiritualRootModel =
      this.playerStateSystem.getModel<SpiritualRootModel>(
        MODEL_NAME.SPIRITUAL_ROOT
      );
    return condition.spiritualRoot.every((element) =>
      spiritualRootModel.hasSpiritualRoot(element)
    );
  }

  private checkKillMonsterCondition(_condition: KillMonsterCondition): boolean {
    return true;
  }

  private checkItemCondition(condition: ItemCondition): boolean {
    const inventoryModel = this.playerStateSystem.getModel<InventoryModel>(
      MODEL_NAME.INVENTORY
    );
    if (!inventoryModel) return false;
    const itemId = condition.itemId;
    const needCount = condition.count;
    const itemCount = inventoryModel.getQuantity(itemId);
    return itemCount >= needCount;
  }

  private checkSectJobCondition(condition: SectJobCondition): boolean {
    const sectModel = this.playerStateSystem.getModel<SectModel>(
      MODEL_NAME.SECT
    );
    if (!sectModel) return false;
    const job = condition.job;
    const currentSectJobConfig = sectModel.getCurrentSectJob();
    if (!currentSectJobConfig) return false;
    return currentSectJobConfig.config.level >= job;
  }

  private checkBattleLevelCondition(condition: BattleLevelCondition): boolean {
    const battleLevelModel = this.playerStateSystem.getModel<BattleLevelModel>(
      MODEL_NAME.BATTLE_LEVEL
    );
    if (!battleLevelModel) return false;
    const level = battleLevelModel.getLevelInfo().level;
    return level >= condition.level;
  }

  private checkSpiritStoneCondition(condition: SpiritStoneCondition): boolean {
    const walletModel = this.playerStateSystem.getModel<WalletModel>(
      MODEL_NAME.WALLET
    );
    if (!walletModel) return false;
    const spiritStone = walletModel.getBalance(CURRENCY_TYPE.SPIRIT_STONE);

    return spiritStone >= condition.count;
  }

  private checkLifeCondition(condition: LifeCondition): boolean {
    const playerProgressModel =
      this.playerStateSystem.getModel<PlayerProgressModel>(
        MODEL_NAME.PLAYER_PROGRESS
      );
    if (!playerProgressModel) return false;
    const years = playerProgressModel.getLifeYears();
    return years >= condition.years;
  }

  private checkCultivationSkillCondition(
    condition: CultivationSkillCondition
  ): boolean {
    const cultivationSkillModel =
      this.playerStateSystem.getModel<CultivationSkillModel>(
        MODEL_NAME.CULTIVATION_SKILL
      );
    if (!cultivationSkillModel) return false;
    return cultivationSkillModel.isCultivationSkillLearned(condition.id);
  }

  private checkAndCondition(condition: AndCondition): boolean {
    return this.checkConditions(condition.conditions);
  }

  private checkOrCondition(condition: OrCondition): boolean {
    for (const subCondition of condition.conditions) {
      if (this.checkCondition(subCondition)) {
        return true;
      }
    }
    return false;
  }

  private checkNotCondition(condition: NotCondition): boolean {
    return !this.checkCondition(condition.condition);
  }
}

// 例子：定义各种解锁条件
// const unlockConditions = {
//   // 装备穿戴条件：等级20且力量50
//   equipAdvancedSword: {
//     type: 'and',
//     conditions: [
//       { type: 'level', minLevel: 20 },
//       { type: 'attribute', attribute: 'strength', minValue: 50 }
//     ] as Condition[]
//   },

//   // 技能学习条件：完成特定任务或达到等级30
//   learnFireSpell: {
//     type: 'or',
//     conditions: [
//       { type: 'quest', questId: 'fire_trial', requiredState: 'completed' },
//       { type: 'level', minLevel: 30 }
//     ] as Condition[]
//   },

//   // 新功能解锁：拥有特定物品且游戏时间超过1小时
//   unlockAlchemy: {
//     type: 'and',
//     conditions: [
//       { type: 'item', itemId: 'alchemy_manual', minCount: 1 },
//       { type: 'time', minPlayTime: 3600 } // 1小时
//     ] as Condition[]
//   },

//   // 复杂条件：完成主线任务且未完成特定分支
//   unlockSecretArea: {
//     type: 'and',
//     conditions: [
//       { type: 'quest', questId: 'main_story_end', requiredState: 'completed' },
//       {
//         type: 'not',
//         condition: { type: 'quest', questId: 'dark_path', requiredState: 'completed' }
//       }
//     ] as Condition[]
//   }
// };
